#!/bin/bash
set -x
ENGINE=${1:-vllm}

export HF_ENDPOINT=https://hf-mirror.com
export HYDRA_FULL_ERROR=1
RAY_DEBUG=0
export VLLM_USE_V1=1

# 环境选择：ascend_large（大规模）, ascend_debug（调试）, cuda_debug（CUDA调试）
env_name=ascend_debug
# env_name=ascend_large
# env_name=cuda_debug

DATE=$(date +%Y%m%d_%H%M%S)
project_name="meeting_schedule"
experiment_name="grpo_meeting_$DATE"

# 根据环境配置参数
if [ "$env_name" = "ascend_large" ]; then
    group_size=4
    node_num=4
    dev_num=8
    train_data_size=`expr $node_num \* 8`
    val_data_size=`expr $node_num \* 8`
    ppo_mini_batch_size=`expr $node_num \* 8`
    train_files=../../data/meeting_schedule/train.parquet
    val_files=../../data/meeting_schedule/val.parquet
    model=/mnt/nas/huggingface_hub/models--Qwen--Qwen2.5-32B-Instruct
    export HUGGINGFACE_HUB_CACHE="/mnt/nas/huggingface_hub/"
    reward_fn_path=/mnt/nas/agentic_system_r/agentic_system/experimental/swe_reward.py
    VLLM_ATTENTION_BACKEND=FLASH_ATTN_VLLM_V1
    tp=8
    cp=1
    GLOO_SOCKET_IFNAME=bond0
    device=npu
    export TENSORBOARD_DIR="/mnt/nas/agenticmodel/log/$project_name/$experiment_name/"
    max_turn=10

elif [ "$env_name" = "ascend_debug" ]; then
    train_data_size=8
    val_data_size=2
    group_size=2
    node_num=1
    dev_num=8
    ppo_mini_batch_size=8
    train_files=/home/xiaocong/agentic_system_r-develop/data/meeting_schedule/train.parquet
    val_files=/home/xiaocong/agentic_system_r-develop/data/meeting_schedule/test.parquet
    model=/data/Qwen2.5-0.5B-Instruct
    export HUGGINGFACE_HUB_CACHE="/mnt/nas/huggingface_hub/"
    reward_fn_path=None
    tp=2
    cp=1
    VLLM_ATTENTION_BACKEND=FLASH_ATTN_VLLM_V1
    device=npu
    GLOO_SOCKET_IFNAME=bond0
    export TENSORBOARD_DIR="/mnt/nas/agenticmodel/log/$project_name/$experiment_name/"
    max_turn=3

elif [ "$env_name" = "cuda_debug" ]; then
    train_data_size=4
    val_data_size=2
    group_size=2
    node_num=1
    dev_num=1
    ppo_mini_batch_size=4
    train_files=./meeting_dataset/train.parquet
    val_files=./meeting_dataset/test.parquet
    model=Qwen/Qwen2.5-7B-Instruct
    export HUGGINGFACE_HUB_CACHE="/home/user/hf_cache"
    reward_fn_path=agentic_system/experimental/swe_reward.py
    export TENSORBOARD_DIR="/home/user/logs/$project_name/$experiment_name/"
    tp=1
    cp=1
    VLLM_ATTENTION_BACKEND=FLASH_ATTN_VLLM_V1
    max_turn=10
    device=cuda
    GLOO_SOCKET_IFNAME=eth0
fi

agent_worker_num=`expr $node_num \* $dev_num`

rollout_mode="async"
if [ "$rollout_mode" = "async" ]; then
    return_raw_chat="True"
fi

echo "======================================"
echo "会议安排系统训练配置"
echo "======================================"
echo "环境: $env_name"
echo "项目: $project_name"
echo "实验: $experiment_name"
echo "训练数据: $train_files"
echo "验证数据: $val_files"
echo "模型: $model"
echo "设备: $device"
echo "节点数: $node_num"
echo "每节点GPU/NPU: $dev_num"
echo "最大轮数: $max_turn"
echo "======================================"

# 启动训练
python3 -m agentic_system.main_ppo \
    algorithm.adv_estimator=grpo \
    data.train_files=$train_files \
    data.val_files=$val_files \
    data.prompt_key="meeting_topic" \
    data.train_batch_size=$train_data_size \
    data.val_batch_size=$val_data_size \
    data.return_raw_chat=$return_raw_chat \
    data.max_prompt_length=3000 \
    data.max_response_length=2048 \
    data.filter_overlong_prompts=False \
    data.truncation='middle' \
    data.return_raw_chat=True \
    actor_rollout_ref.model.path=$model \
    actor_rollout_ref.model.trust_remote_code=True \
    actor_rollout_ref.actor.optim.lr=1e-6 \
    actor_rollout_ref.model.use_remove_padding=True \
    actor_rollout_ref.actor.use_torch_compile=False \
    actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu=1 \
    actor_rollout_ref.actor.use_kl_loss=True \
    actor_rollout_ref.actor.kl_loss_coef=0.01 \
    actor_rollout_ref.actor.kl_loss_type=low_var_kl \
    actor_rollout_ref.actor.ulysses_sequence_parallel_size=$cp \
    actor_rollout_ref.ref.ulysses_sequence_parallel_size=$cp \
    actor_rollout_ref.model.enable_gradient_checkpointing=True \
    actor_rollout_ref.actor.fsdp_config.param_offload=False \
    actor_rollout_ref.actor.fsdp_config.optimizer_offload=False \
    actor_rollout_ref.rollout.log_prob_micro_batch_size_per_gpu=1 \
    actor_rollout_ref.rollout.tensor_model_parallel_size=$tp \
    actor_rollout_ref.rollout.max_model_len=16384 \
    actor_rollout_ref.rollout.multi_turn.enable=True \
    actor_rollout_ref.rollout.multi_turn.max_assistant_turns=$max_turn \
    actor_rollout_ref.rollout.name=$ENGINE \
    actor_rollout_ref.rollout.n=$group_size \
    actor_rollout_ref.rollout.mode=$rollout_mode \
    actor_rollout_ref.rollout.gpu_memory_utilization=0.85 \
    actor_rollout_ref.rollout.enable_chunked_prefill=True \
    actor_rollout_ref.rollout.enforce_eager=False \
    actor_rollout_ref.rollout.load_format=auto \
    actor_rollout_ref.rollout.free_cache_engine=False \
    actor_rollout_ref.rollout.val_kwargs.temperature=0.6 \
    actor_rollout_ref.rollout.val_kwargs.top_p=0.9 \
    actor_rollout_ref.rollout.val_kwargs.do_sample=True \
    actor_rollout_ref.rollout.prompt_length=6000 \
    actor_rollout_ref.rollout.response_length=2048 \
    actor_rollout_ref.ref.log_prob_micro_batch_size_per_gpu=1 \
    actor_rollout_ref.ref.fsdp_config.param_offload=True \
    actor_rollout_ref.actor.ppo_mini_batch_size=$ppo_mini_batch_size \
    ++algorithm.use_kl_in_reward=False \
    +env.seed=0 \
    +env.max_steps=$max_turn \
    +env.rollout.n=$group_size \
    reward_model.enable=False \
    reward_model.reward_manager=naive \
    trainer.critic_warmup=0 \
    trainer.logger=['console',"tensorboard"] \
    trainer.project_name="$project_name" \
    trainer.experiment_name="$experiment_name" \
    trainer.default_local_dir="/mnt/nas/agenticmodel/checkpoints/$project_name/$experiment_name" \
    trainer.rollout_data_dir="/mnt/nas/agenticmodel/log/$project_name/$experiment_name/rollout" \
    trainer.validation_data_dir="/mnt/nas/agenticmodel/log/$project_name/$experiment_name/val" \
    +trainer.tensorboard_dir="/mnt/nas/agenticmodel/log/$project_name/$experiment_name/" \
    +ray_kwargs.ray_init.runtime_env.env_vars.HF_ENDPOINT=https://hf-mirror.com \
    +ray_kwargs.ray_init.runtime_env.env_vars.VLLM_USE_V1=\"1\" \
    +ray_kwargs.ray_init.runtime_env.env_vars.RAY_DEBUG=\"$RAY_DEBUG\" \
    +ray_kwargs.ray_init.runtime_env.env_vars.HUGGINGFACE_HUB_CACHE=$HUGGINGFACE_HUB_CACHE \
    +ray_kwargs.ray_init.runtime_env.env_vars.TENSORBOARD_DIR=/mnt/nas/agenticmodel/log/$project_name/$experiment_name/ \
    +ray_kwargs.ray_init.runtime_env.env_vars.GLOO_SOCKET_IFNAME=$GLOO_SOCKET_IFNAME \
    +ray_kwargs.ray_init.runtime_env.env_vars.RAY_IGNORE_UNHANDLED_ERRORS=\"1\" \
    +ray_kwargs.ray_init.runtime_env.env_vars.VLLM_ATTENTION_BACKEND=$VLLM_ATTENTION_BACKEND \
    trainer.device=$device \
    trainer.n_gpus_per_node=$dev_num \
    trainer.nnodes=$node_num \
    trainer.save_freq=10 \
    trainer.test_freq=5 \
    trainer.total_epochs=100 \
    trainer.balance_batch=False \
    trainer.val_before_train=False 2>&1 | tee logs/meeting_$experiment_name.log